#include <iostream>
#include <string>
#include <vector>

static const std::string base64_chars = 
             "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
             "abcdefghijklmnopqrstuvwxyz"
             "0123456789+/";

static inline bool is_base64(unsigned char c) {
    return (isalnum(c) || (c == '+') || (c == '/'));
}

// Base64编码
std::string base64_encode(const std::vector<unsigned char>& data) {
    std::string encoded_string;
    int val = 0;
    int valb = -6;
    for (unsigned char c : data) {
        val = (val << 8) + c;
        valb += 8;
        while (valb >= 0) {
            encoded_string.push_back(base64_chars[(val >> valb) & 0x3F]);
            valb -= 6;
        }
    }
    if (valb > -6) encoded_string.push_back(base64_chars[((val << 8) >> (valb + 8)) & 0x3F]);
    while (encoded_string.size() % 4) encoded_string.push_back('=');
    return encoded_string;
}


// Base64解码
std::vector<unsigned char> base64_decode(const std::string& encoded_string) {
    int in_len = encoded_string.size();
    int i = 0;
    int in_ = 0;
    int val = 0;
    int valb = -8;
    std::vector<unsigned char> decoded_bytes;

    while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
        val = (val << 6) + base64_chars.find(encoded_string[in_]);
        valb += 6;
        if (valb >= 0) {
            decoded_bytes.push_back((val >> valb) & 0xFF);
            valb -= 8;
        }
        in_++;
    }
    return decoded_bytes;
}

// int main() {
//     std::string input = "Hello, World!";
//     std::vector<unsigned char> data(input.begin(), input.end());

//     std::string encoded = base64_encode(data);
//     std::cout << "Encoded: " << encoded << std::endl;

//     std::vector<unsigned char> decoded = base64_decode(encoded);
//     std::string decoded_str(decoded.begin(), decoded.end());
//     std::cout << "Decoded: " << decoded_str << std::endl;

//     return 0;
// }
